#include <strings.h>
#include <stdio.h>
#include <netdb.h>

#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERV_PORT 9877
#define MAX_LINE  4096
#define SA  struct sockaddr

void dg_echo(int sockfd, SA * pcliAddr, socklen_t cliLen)
{
	int n;
	socklen_t len;
	
	for (;;) {
		len = cliLen;
		char mesg[MAX_LINE] = {0};
		n = recvfrom(sockfd, mesg, MAX_LINE, 0, pcliAddr, &len);
		//获取地址方法1
		//char cliAddr[16]={0};
		//inet_ntop(AF_INET, &((sockaddr_in*)pcliAddr)->sin_addr, cliAddr,sizeof(cliAddr));

		//获取地址方法2
		char hostAddr[NI_MAXHOST]={0}, cliPort[NI_MAXHOST]={0};
		getnameinfo(pcliAddr, cliLen,hostAddr,sizeof(hostAddr), 
			cliPort, sizeof(cliPort), NI_DGRAM|NI_NUMERICHOST|NI_NUMERICSERV);
		printf("recv from host=%s, serv=%s data=%s, n=%d\n",hostAddr,cliPort, mesg, n);	

		sendto(sockfd, mesg, n, 0, pcliAddr, len);
	}
}

int main(int argc, char**argv)
{
	int sockfd;
	struct sockaddr_in servAddr, cliAddr;
	if(0>(sockfd = socket(AF_INET, SOCK_DGRAM, 0)))
	{
		printf("create socket failed.");
		return 0;
	}
	bzero(&servAddr, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_port  = htons(SERV_PORT);
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(sockfd, (SA*) & servAddr, sizeof(servAddr));
	dg_echo(sockfd, (SA*) & cliAddr, sizeof(cliAddr));
}
